import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.*;

class TQuery{
	public TWebMessage primary;
	public String secondary;
}

class InputThread extends Thread{
	TClient cl;
	InputThread(String name, TClient c){
		super(name);
		cl = c;
	}
	public void run(){
		cl.StartReceiveingMessages();
	}
}

class OutputThread extends Thread {
	TClient cl;
	OutputThread(String name, TClient c){
		super();
		cl = c;
	}
	public void run(){
		cl.StartSendingMessages();
	}
}

public class TClient {
	private Socket sock;
	private AtomicBoolean isRunning;
	private BlockingQueue<TQuery> queries;
	private BlockingQueue<TWebMessage> outcoming;
	private ObjectInputStream in;
	private ObjectOutputStream out;
	public TQuery Poll(){
		try {
			return queries.take();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	public TClient(){
		queries = new LinkedBlockingQueue<TQuery>();
		outcoming = new LinkedBlockingQueue<TWebMessage>();
		isRunning = new AtomicBoolean(true);
	}
	
	public void Connect(InetAddress addr, int port, String nickname){
		try {
			sock = new Socket(addr, port);
			out = new ObjectOutputStream(sock.getOutputStream());
			out.flush();
			in = new ObjectInputStream(sock.getInputStream());
			out.writeObject(nickname);			
					
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		new InputThread("ITh",this).start();
		new OutputThread("OTh", this).start();
	}
	public void StartSendingMessages(){
		while (isRunning.get()){
			TWebMessage current;
			try {
				current = outcoming.take();
				SendMessage(current);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void AddMessage(TWebMessage a){
		outcoming.add(a);
	}
	
	public void StartReceiveingMessages(){
		try {
			while (isRunning.get()){
				TQuery input = new TQuery();
				try {
					input.primary = (TWebMessage) in.readObject();
					if (input.primary.purpose == MessagesDescription.PLAYERS_NICKNAME)
						input.secondary = (String) in.readObject();
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
				if (input.primary.purpose != -1)
					queries.add(input);
			}
			sock.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	private void SendMessage(Serializable msg){
		try {
			out.writeObject(msg);
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	
	public void SendEnterGame(){
		TWebMessage msg = new TWebMessage();
		msg.purpose = MessagesDescription.ENTERING_GAME;
		AddMessage(msg);
	}
	
	public void SendDecision(int decision){
		TWebMessage msg = new TWebMessage();
		msg.purpose = MessagesDescription.PLAYERS_DECISION;
		msg.args[0] = decision;
		AddMessage(msg);
		
	}
	
	public void Disconnect(){
		isRunning.set(false);
	}
	
}
